package com.itheima.app.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.Movement;
import com.itheima.service.db.FreezeService;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.DateFormatUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.ErrorResult;
import com.itheima.vo.MovementVo;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class MovementManager {

    @Autowired
    private OssTemplate ossTemplate;

    @DubboReference
    private MovementService movementService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @DubboReference
    private FreezeService freezeService;

    @Autowired
    private MQMovementManager mqMovementManager;

    @Autowired
    private UserManager userManager;

    // 发布动态
    public ResponseEntity saveMovement(Movement movement, MultipartFile[] imageContent) throws Exception {
        // 1.获取线程内用户id
        Long userId = UserHolder.get().getId();

        //是否允许发布动态
        if(userManager.findByFreeze(userId,3)){
            String time = freezeService.findByFreeze(userId).getFinishTime().toString();
            return ResponseEntity.status(501).body(ErrorResult.freezeByMovementError(DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss")));//501指示 HTTP 服务器不支持完成请求所需的功能
        }
        // 2.上传图片到oss
        List<String> medias = new ArrayList<>();
        if (ArrayUtil.isNotEmpty(imageContent)) {
            for (MultipartFile multipartFile : imageContent) {
                String picUrl = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
                medias.add(picUrl);
            }
        }
        // 3.封装movement
        movement.setId(ObjectId.get()); // 主键id
        movement.setUserId(userId); // 发布人id
        movement.setMedias(medias); // 发布图片
        movement.setState(0);
        movement.setCreated(System.currentTimeMillis()); // 发布时间
        movement.setSeeType(1); // TODO 1.0版本所有人都可以看

        // 4.调用rpc发布
        movementService.saveMovement(movement);

        // 5.发送mq（审核）
        rabbitTemplate.convertAndSend("tanhua.movement.state", movement.getId().toHexString());

        // 6.发送mq（推荐）
        mqMovementManager.sendMovement(userId, movement.getId(), MQMovementManager.MOVEMENT_PUBLISH);

        return ResponseEntity.ok("ok");
    }

    @DubboReference
    private UserInfoService userInfoService;

    // 查看个人动态
    public ResponseEntity findMyMovement(Long userId, Integer pageNum, Integer pageSize) {
        // 1.调用rpc查询动态详情分页
        PageBeanVo pageBeanVo = movementService.findMyMovement(userId, pageNum, pageSize);
        // 2.封装movementVo
        // 2.1 获取movementList
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        // 2.2 声明voList
        List<MovementVo> voList = new ArrayList<>();
        // 2.3 遍历movementList 封装 vo
        if (CollectionUtil.isNotEmpty(movementList)) {
            for (Movement movement : movementList) {
                // 创建vo对象
                MovementVo vo = new MovementVo();
                // 注意：一定要要设置userInfo、再movement
                UserInfo userInfo = userInfoService.findUserInfoById(movement.getUserId());
                vo.setUserInfo(userInfo); // 设置用户
                vo.setMovement(movement); // 设置动态

                // 判断当前用户是否对此动态点赞
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, UserHolder.get().getId(), movement.getId().toHexString()))) {
                    vo.setHasLiked(1);
                }

                // 添加到voList
                voList.add(vo);
            }
        }
        // 3.将movementVo设置到分页对象
        pageBeanVo.setItems(voList);
        // 4.返回pbv
        return ResponseEntity.ok(pageBeanVo);
    }

    // 查看好友动态
    public ResponseEntity findFriendMovement(Integer pageNum, Integer pageSize) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc查询好友动态详情分页
        PageBeanVo pageBeanVo = movementService.findFriendMovement(userId, pageNum, pageSize);
        // 3.封装movementVo
        // 3.1 获取movementList
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        // 3.2 声明voList
        List<MovementVo> voList = new ArrayList<>();
        // 3.3 遍历movementList
        if (CollectionUtil.isNotEmpty(movementList)) {
            for (Movement movement : movementList) {
                // 创建vo
                MovementVo vo = new MovementVo();
                // 先封装 userInfo
                UserInfo userInfo = userInfoService.findUserInfoById(movement.getUserId());
                vo.setUserInfo(userInfo);
                // 再封装 movement
                vo.setMovement(movement);
                // 判断当前用户是否对此动态点赞
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, UserHolder.get().getId(), movement.getId().toHexString()))) {
                    vo.setHasLiked(1);
                }

                // 添加到voList中
                voList.add(vo);
            }
        }

        // 4.将movementVo设置到分页对象
        pageBeanVo.setItems(voList);

        // 5.返回分页对象
        return ResponseEntity.ok(pageBeanVo);
    }

    // 查看推荐动态
    public ResponseEntity findRecommendMovement(Integer pageNum, Integer pageSize) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc查询推荐动态详情分页
        PageBeanVo pageBeanVo = movementService.findRecommendMovement(userId, pageNum, pageSize);
        // 3.封装movmeentVo
        // 3.1 获取movementList
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        // 3.2 声明voList
        List<MovementVo> voList = new ArrayList<>();
        // 3.3 遍历movementList
        if (CollectionUtil.isNotEmpty(movementList)) {
            for (Movement movement : movementList) {
                // 创建vo
                MovementVo vo = new MovementVo();
                // 设置用户信息
                UserInfo userInfo = userInfoService.findUserInfoById(movement.getUserId());
                vo.setUserInfo(userInfo);
                // 设置动态详情
                vo.setMovement(movement);
                // 判断当前用户是否对此动态点赞
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, UserHolder.get().getId(), movement.getId().toHexString()))) {
                    vo.setHasLiked(1);
                }
                // 判断当前用户是否对此动态喜欢
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, UserHolder.get().getId(), movement.getId().toHexString()))) {
                    vo.setHasLoved(1);
                }
                // 添加到voList
                voList.add(vo);
            }
        }
        // 4.将vo设置到分页对象
        pageBeanVo.setItems(voList);

        // 5.返回分页对象
        return ResponseEntity.ok(pageBeanVo);
    }

    @DubboReference
    private CommentService commentService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    // 动态点赞
    public ResponseEntity setMovementLike(String publishId) {
        // 1.获取线程呢你userId
        Long userId = UserHolder.get().getId();
        // 2.根据publishId查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));
        // 3.封装comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis()); // 点赞时间
        comment.setPublishId(movement.getId()); // 动态id
        comment.setCommentType(1); // 操作类型
        comment.setUserId(userId); // 操作人
        comment.setPublishUserId(movement.getUserId()); // 动态发布人id
        // 4.调用rpc保存
        Integer likeCount = commentService.saveComment(comment);
        // 5.redis存储点赞状态
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, publishId), "1");

        // 发送mq（推荐）
        mqMovementManager.sendMovement(userId, movement.getId(), MQMovementManager.MOVEMENT_LIKE);

        return ResponseEntity.ok(likeCount);
    }

    // 动态取消点赞
    public ResponseEntity removeMovementLike(String publishId) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc删除
        Integer likeCount = commentService.removeComment(new ObjectId(publishId), userId, 1);
        // 3.删除redis点赞状态
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, publishId));

        return ResponseEntity.ok(likeCount);
    }

    // 动态喜欢
    public ResponseEntity setMovementLove(String publishId) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.根据publishId查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));
        // 3.封装comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis()); // 操作时间
        comment.setPublishId(movement.getId());// 动态id
        comment.setCommentType(3);// 操作类型
        comment.setUserId(userId);// 操作人
        comment.setPublishUserId(movement.getUserId()); // 动态发布人id
        // 4.调用 rpc保存
        Integer loveCount = commentService.saveComment(comment);
        // 5.向redis存储喜欢状态
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, publishId), "1");
        return ResponseEntity.ok(loveCount);
    }

    // 动态取消喜欢
    public ResponseEntity removeMovementLove(String publishId) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc删除
        Integer loveCount = commentService.removeComment(new ObjectId(publishId), userId, 3);
        // 3.从redis中清除喜欢状态
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, publishId));
        return ResponseEntity.ok(loveCount);
    }

    // 查看单条动态
    public ResponseEntity findeMovemetnVoDetail(String publishId) {
        // 1.调用rpc查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));
        // 2.封装movementVo
        MovementVo vo = new MovementVo();
        // 设置userInfo
        UserInfo userInfo = userInfoService.findUserInfoById(movement.getUserId());
        vo.setUserInfo(userInfo);
        // 设置movement
        vo.setMovement(movement);
        // 3.返回vo
        return ResponseEntity.ok(vo);
    }

    // 查看动态评论列表
    public ResponseEntity findCommentVo(String publishId, Integer pageNum, Integer pageSize) {
        // 1.调用rpc分页查询评论分页对象
        PageBeanVo pageBeanVo = commentService.findByPage(new ObjectId(publishId), 2, pageNum, pageSize);

        // 2.封装commentVo
        // 2.1 获取 commentList
        List<Comment> commentList = (List<Comment>) pageBeanVo.getItems();
        // 2.2 声明 voList
        List<CommentVo> voList = new ArrayList<>();
        // 2.3 遍历 commentList
        if (CollectionUtil.isNotEmpty(commentList)) {
            for (Comment comment : commentList) {
                // 创建vo
                CommentVo vo = new CommentVo();
                vo.setId(comment.getId().toHexString()); // 评论id
                UserInfo userInfo = userInfoService.findUserInfoById(comment.getUserId());
                vo.setAvatar(userInfo.getAvatar());// 评论人头像
                vo.setNickname(userInfo.getNickname()); // 评论人昵称
                vo.setContent(comment.getContent()); // 评论内容
                vo.setCreateDate(DateFormatUtil.format(new Date(comment.getCreated()))); // 评论时间

                // 添加到voList
                voList.add(vo);

            }
        }
        // 3.将vo设置到分页对象
        pageBeanVo.setItems(voList);

        // 4.返回分页对象
        return ResponseEntity.ok(pageBeanVo);
    }

    // 发表评论
    public ResponseEntity setMovementComment(String publishId, String content) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();

        //是否允许发布评论
        if(userManager.findByFreeze(userId,2)){
            String time = freezeService.findByFreeze(userId).getFinishTime().toString();
            return ResponseEntity.status(501).body(ErrorResult.freezeByCommentError(DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss")));//501指示 HTTP 服务器不支持完成请求所需的功能
        }

        // 2.查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));
        // 3.封装comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(movement.getId());
        comment.setCommentType(2); // 操作类型
        comment.setUserId(userId);// 操作人
        comment.setPublishUserId(movement.getUserId()); // 动态发布人
        comment.setContent(content);
        // 4.调用rpc保存
        commentService.saveComment(comment);
        return ResponseEntity.ok("ok");
    }
}
